PART 2: Exploring Data Distribution
There are altogether 81 variables in the dataset. We will go over each column one by one to understand its details and then decide the corresponding cleaning method.
- opportunity_id: the unique identifer of each applicant.
- application_term: Term applied to program There is a sudden drop in number of applications for 1st tier admit in 2015, so I checked the whole dataset to see if the sudden drop is due to the drop in total number of application, and find that the drop is universal among all students. –> OUR BUSINESS OBJECTIVE MAY NOT BE FEASIBLE!
# class(t1$application_term) #data type is character
#
# # convert the data type to factor and reorder the level to match actual semesters timeline
# t1$application_term = as.factor(t1$application_term)
# levels(t1$application_term) = levels(t1$application_term)[c(7, 1, 8, 2, 9, 3, 10, 4, 5, 6)]
# levels(t1$application_term)
#
# # draw the plot
# ggplot(t1, aes(x = application_term))+
# geom_bar(fill="#999999")+
# labs(title="Distribution of application_term",
# x="application_term",
# y="Count")+
# theme(plot.title = element_text(hjust = 0.5),
# axis.text.x = element_text(angle = 45, hjust = 1))
# convert the data type to factor and reorder the level to match actual semesters timeline
data$application_term = as.factor(data$application_term)
levels(data$application_term) = levels(data$application_term)[c(10, 1, 11, 2, 7, 12, 3, 8, 13, 4, 5, 9, 14, 6)]
# draw the plot (grey is all students, red is 1st tier students)
data%>%
filter(!is.na(application_term))%>%
ggplot(aes(x = application_term))+
geom_bar(fill="#999999")+
labs(title="Distribution of application_term (for all applications)",
x="application_term",
y="Count")+
theme(plot.title = element_text(hjust = 0.5),
axis.text.x = element_text(angle = 45, hjust = 1))+
geom_bar(data = t1, fill="red")+
labs(title="Distribution of application_term (for all applications)",
x="application_term",
y="Count")+
theme(plot.title = element_text(hjust = 0.5),
axis.text.x = element_text(angle = 45, hjust = 1))

# draw the count for students who confirmed offer
data%>%
filter(response == "Confirmed")%>%
ggplot(aes(x = application_term))+
geom_bar(fill="#999999")+
labs(title="Distribution of application_term (for confirmed stduents)",
x="application_term",
y="Count")+
theme(plot.title = element_text(hjust = 0.5),
axis.text.x = element_text(angle = 45, hjust = 1))

So we performed the rest of the EDA, on the entire dataset 3. degree_posted: When their undergraduate degree conferred 1 outlier
# draw the plot
data%>%
filter(degree_posted < "2019-01-01")%>%
ggplot(aes(x = degree_posted))+
geom_point(stat = "count")+
labs(title = 'Distribution of undergraduate degree conferred date')+
theme(plot.title = element_text(hjust = 0.5),
text = element_text(size=15))

- application_received_date: Date their application was received many NAs
# aggregated
data%>%
filter(!is.na(application_received_date))%>%
ggplot(aes(x = as.factor(month(application_received_date))))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of application_received_date (agg. to months)',
x = "month")+
theme(plot.title = element_text(hjust = 0.5),
text = element_text(size = 15))

# across all years
data%>%
filter(!is.na(application_received_date))%>%
ggplot(aes(x = application_received_date))+
geom_point(stat = "count")+
labs(title = 'Distribution of application_received_date',
x = "time")+
theme(plot.title = element_text(hjust = 0.5),
text = element_text(size = 15))

- file_status_completed_date: Date their application file was completed
# aggregated to months
data%>%
filter(file_status_completed_date < "2019-01-01")%>%
ggplot(aes(x = as.factor(month(file_status_completed_date))))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of file_status_completed_date (agg. to months)',
x = "month")+
theme(plot.title = element_text(hjust = 0.5),
text = element_text(size = 15))

# across all years
data%>%
filter(file_status_completed_date < "2019-01-01")%>%
ggplot(aes(x = file_status_completed_date))+
geom_point(stat = "count")+
labs(title = 'Distribution of file_status_completed_date',
x = "time")+
theme(plot.title = element_text(hjust = 0.5),
text = element_text(size = 15))

- decision_date: Date of the admit or deny decision for their application There is one outlier in this field and is apparently a typo, which is excluded from the dataset
# draw the plot
data%>%
filter(decision_date < "2019-01-01")%>%
ggplot(aes(x = as.factor(month(decision_date))))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of decision_date',
x = "month")+
theme(plot.title = element_text(hjust = 0.5),
text = element_text(size = 15))

# across all years
data%>%
filter(decision_date < "2019-01-01")%>%
ggplot(aes(x = decision_date))+
geom_point(stat = "count")+
labs(title = 'Distribution of decision_date',
x = "time")+
theme(plot.title = element_text(hjust = 0.5),
text = element_text(size = 15))

- application_cleaned_date: Date their application was processed after receiving
# draw the plot
data%>%
filter(!is.na(application_cleaned_date))%>%
ggplot(aes(x = as.factor(month(application_cleaned_date))))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of application_cleaned_date',
x = "month")+
theme(plot.title = element_text(hjust = 0.5),
text = element_text(size = 15))

# across all years
data%>%
filter(!is.na(application_cleaned_date))%>%
ggplot(aes(x = application_cleaned_date))+
geom_point(stat = "count")+
labs(title = 'Distribution of application_cleaned_date',
x = "time")+
theme(plot.title = element_text(hjust = 0.5),
text = element_text(size = 15))

- deposit_received_date
# draw the plot
data%>%
filter(!is.na(deposit_received_date))%>%
ggplot(aes(x = as.factor(month(deposit_received_date))))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of deposit_received_date',
x = "month")+
theme(plot.title = element_text(hjust = 0.5),
text = element_text(size = 15))

# across all years
data%>%
filter(!is.na(deposit_received_date))%>%
ggplot(aes(x = deposit_received_date))+
geom_point(stat = "count")+
labs(title = 'Distribution of deposit_received_date',
x = "time")+
theme(plot.title = element_text(hjust = 0.5),
text = element_text(size = 15))

- department: Department of students
# draw the plot and exclude all NAs (many NAs)
data%>%
filter(!is.na(department))%>%
ggplot(aes(x = department))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of department')+
theme(plot.title = element_text(hjust = 0.5),
text = element_text(size = 15))

- undergraduate_gpa: calculated by USC
#plot
data%>%
filter(undergraduate_gpa != 0)%>%
ggplot(aes(x = undergraduate_gpa))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of undergraduate_gpa')+
theme(plot.title = element_text(hjust = 0.5),
text = element_text(size = 15))

- self_reported_gpa Outliers with self reported gpa greater than 5 and equals to 0 (should be cleaned)
#plot
data%>%
filter(self_reported_gpa <= 4 & self_reported_gpa != 0)%>%
ggplot(aes(x = self_reported_gpa))+
geom_point(stat = "count")+
labs(title = 'Distribution of self_reported_gpa')+
theme(plot.title = element_text(hjust = 0.5),
text = element_text(size = 15))

#plot self_reported_gpa with undergraduate gpa calculted by USC
data%>%
filter(self_reported_gpa <= 4 & self_reported_gpa != 0)%>%
filter(undergraduate_gpa != 0)%>%
ggplot(aes(x = undergraduate_gpa))+
geom_bar(fill = "#999999")+
geom_point(aes(x = self_reported_gpa), stat = "count", color = "red")+
labs(title = 'self_reported_gpa (red) against undergraduate_gpa')+
theme(plot.title = element_text(hjust = 0.5),
text = element_text(size = 15))

- first_reviewer_id
#plot
data%>%
filter(!is.na(first_reviewer_id))%>%
ggplot(aes(x = first_reviewer_id))+
geom_point(stat = "count")+
labs(title = 'Distribution of first_reviewer_id')+
theme(plot.title = element_text(hjust = 0.5),
axis.text.x = element_text(angle = 45, hjust = 1))

- first_review_exp: First reviewer score for experience
data%>%
ggplot(aes(x = first_review_exp))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of first_review_exp')+
theme(plot.title = element_text(hjust = 0.5))

- first_review_sop: First reviewer score for statement of purpose
data%>%
ggplot(aes(x = first_review_sop))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of first_review_sop')+
theme(plot.title = element_text(hjust = 0.5))

- first_review_gpa: First reviewer score for GPA (undergrad and grad)
data%>%
ggplot(aes(x = first_review_gpa))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of first_review_gpa')+
theme(plot.title = element_text(hjust = 0.5))

- first_review_lor: letters of recommendation
data%>%
ggplot(aes(x = first_review_lor))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of first_review_lor')+
theme(plot.title = element_text(hjust = 0.5))

- first_review_total: total score
data%>%
ggplot(aes(x = first_review_total))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of first_review_total')+
theme(plot.title = element_text(hjust = 0.5))

- second_reviewer_id
#plot
data%>%
filter(!is.na(second_reviewer_id))%>%
ggplot(aes(x = second_reviewer_id))+
geom_point(stat = "count")+
labs(title = 'Distribution of second_reviewer_id')+
theme(plot.title = element_text(hjust = 0.5),
axis.text.x = element_text(angle = 45, hjust = 1))

- second_review_exp: second reviewer score for experience
data%>%
ggplot(aes(x = second_review_exp))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of second_review_exp')+
theme(plot.title = element_text(hjust = 0.5))

- second_review_sop: second reviewer score for statement of purpose
data%>%
ggplot(aes(x = second_review_sop))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of second_review_sop')+
theme(plot.title = element_text(hjust = 0.5))

- second_review_gpa: second reviewer score for GPA (undergrad and grad)
data%>%
ggplot(aes(x = second_review_gpa))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of second_review_gpa')+
theme(plot.title = element_text(hjust = 0.5))

concentration/department_interest: Department of student. This one is the unofficial one (“department” is the official one), probably manually filled and thus is very messy. We can directly use
first_review_lor: letters of recommendation
data%>%
ggplot(aes(x = second_review_lor))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of second_review_lor')+
theme(plot.title = element_text(hjust = 0.5))

- second_review_total: total score
data%>%
ggplot(aes(x = second_review_total))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of second_review_total')+
theme(plot.title = element_text(hjust = 0.5))

billing_state/province Manually input data and thus very messy. Lots of inconsistent writing of same geographical location, such as “CA” and “California”.
billing_zip/postal_code
billing_country
data$billing_country[data$billing_country %in% c("united States", "United", "USA", "United States of America", "CA")] = "United States"
data%>%
filter(!is.na(billing_country))%>%
group_by(billing_country)%>%
summarise(count = n())%>%
ggplot(aes(x = reorder(billing_country, -count), y = count))+
geom_bar(stat = "identity", fill = "#999999")+
labs(title = 'Distribution of billing_country')+
theme(plot.title = element_text(hjust = 0.5),
axis.text.x = element_text(angle = 45, hjust = 1))

- distance_to_campus
data%>%
ggplot(aes(x = distance_to_campus))+
geom_point(stat = "count")+
labs(title = 'Distribution of distance_to_campus')+
theme(plot.title = element_text(hjust = 0.5))

- program_length
data$program_length = as.factor(data$program_length)
levels(data$program_length) = levels(data$program_length)[c(2, 4, 6, 7, 1, 8, 3, 5)]
data%>%
filter(!is.na(program_length))%>%
ggplot(aes(x = program_length))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of program_length')+
theme(plot.title = element_text(hjust = 0.5))

student_id (can be used as the unique identifier as “opportunity id”)
post_code: meaning program of study
data%>%
filter(!is.na(post_code) & !post_code %in% c("Fall 2015", "1645;264", "264;1412", "264;1411", "264;264", "272;264"))%>%
group_by(post_code)%>%
summarise(count = n())%>%
ggplot(aes(x = reorder(post_code, -count), y = count))+
geom_bar(stat = "identity", fill = "#999999")+
labs(title = 'Distribution of post_code',
x = 'post_code')+
theme(plot.title = element_text(hjust = 0.5))

- post_code_expired (whether the applicant switched from another program)
data%>%
ggplot(aes(x = post_code_expired))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of post_code_expired')+
theme(plot.title = element_text(hjust = 0.5))

- file_status
data%>%
ggplot(aes(x = file_status))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of file_status')+
theme(plot.title = element_text(hjust = 0.5))

#remove NA
data%>%
filter(!is.na(file_status))%>%
ggplot(aes(x = file_status))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of file_status')+
theme(plot.title = element_text(hjust = 0.5))

- birth_date: dob of the applicant
data%>%
filter(!is.na(birth_date) & birth_date < "2000-01-01")%>%
ggplot(aes(x = as.factor(year(birth_date))))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of birth_date',
x = 'birth_date (year)')+
scale_x_discrete(breaks = seq(1930, 2000, by = 10))+
theme(plot.title = element_text(hjust = 0.5),
text = element_text(size=15))

- ethnicity
data%>%
filter(!is.na(ethnicity))%>%
group_by(ethnicity)%>%
summarise(count = n())%>%
ggplot(aes(x = reorder(ethnicity, -count), y = count))+
geom_bar(stat = "identity", fill = "#999999")+
labs(title = 'Distribution of ethnicity')+
theme(plot.title = element_text(hjust = 0.5),
axis.text.x = element_text(angle = 45, hjust = 1))

- gender
data%>%
filter(!is.na(gender))%>%
ggplot(aes(x = gender))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of gender')+
theme(plot.title = element_text(hjust = 0.5))

- campus: Campus of study of applicant
data%>%
filter(!is.na(campus))%>%
ggplot(aes(x = campus))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of campus')+
theme(plot.title = element_text(hjust = 0.5),
axis.text.x = element_text(angle = 45, hjust = 1))

- first_generation
data%>%
filter(!is.na(first_generation))%>%
ggplot(aes(x = first_generation))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of first_generation')+
theme(plot.title = element_text(hjust = 0.5))

- post_code_account
data%>%
filter(!is.na(post_code) & !post_code %in% c("Fall 2015", "1645;264", "264;1412", "264;1411", "264;264", "272;264"))%>%
group_by(post_code_account)%>%
summarise(count = n())%>%
ggplot(aes(x = reorder(post_code_account, -count), y = count))+
geom_bar(stat = "identity", fill = "#999999")+
labs(title = 'Distribution of post_code_account',
x = 'post_code_account')+
theme(plot.title = element_text(hjust = 0.5))

- registered_units_account
data%>%
filter(!is.na(registered_units_account))%>%
ggplot(aes(x = registered_units_account))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of registered_units_account')+
theme(plot.title = element_text(hjust = 0.5))

- department_student_account
data%>%
filter(!is.na(department_student_account))%>%
ggplot(aes(x = department_student_account))+
geom_bar(fill = "#999999")+
labs(title = 'Distribution of department_student_account')+
theme(plot.title = element_text(hjust = 0.5))

LS0tCnRpdGxlOiAiRURBLVJlY3J1aXRpbmcgQ2FzZSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CiMgTG9hZGluZyBuZWNlc3NhcnkgcGFja2FnZXMgYW5kIGRhdGFzZXRzCmxpYnJhcnkocmVhZHIpCmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShwbHlyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHNjYWxlcykKCmRhdGEgPSByZWFkX2V4Y2VsKCJDYXNlICMyIC0gVVNDIFJlY3J1aXRpbmcgU3RyYXRlZ3kgQ2FzZSAtIERBVEEgLSBzZXB0IDIwMTgueGxzeCIpCmNvZGVib29rID0gcmVhZF9leGNlbCgiQ0FTRSAjMiAtIFJlY3J1aXRpbmcgU3RyYXRlZ3kgQ29kZUJvb2s5LjUuMTgueGxzeCIpCgojIFJlcGxhY2luZyBhbGwgc3BlY2lhbCBjaGFyYWN0ZXIgaW4gdGhlIGNvbHVtbiBuYW1lcyB0byB1bmRlcmxpbmUgIl8iIG9yIHNpbXBseSByZW1vdmUgdGhlbQpjb2xuYW1lcyhkYXRhKSA9IGdzdWIoIi0iLCAiXyIsIGNvbG5hbWVzKGRhdGEpKQpjb2xuYW1lcyhkYXRhKSA9IGdzdWIoIiAiLCAiXyIsIGNvbG5hbWVzKGRhdGEpKQpjb2xuYW1lcyhkYXRhKSA9IGdzdWIoIi8iLCAiXyIsIGNvbG5hbWVzKGRhdGEpKQpjb2xuYW1lcyhkYXRhKSA9IGdzdWIoIlxcKCIsICIiLCBjb2xuYW1lcyhkYXRhKSkKY29sbmFtZXMoZGF0YSkgPSBnc3ViKCJcXCkiLCAiIiwgY29sbmFtZXMoZGF0YSkpCgpjb2RlYm9vayRGaWVsZCA9IGdzdWIoIi0iLCAiXyIsIGNvZGVib29rJEZpZWxkKQpjb2RlYm9vayRGaWVsZCA9IGdzdWIoIiAiLCAiXyIsIGNvZGVib29rJEZpZWxkKQpjb2RlYm9vayRGaWVsZCA9IGdzdWIoIlxcKCIsICIiLCBjb2RlYm9vayRGaWVsZCkKY29kZWJvb2skRmllbGQgPSBnc3ViKCJcXCkiLCAiIiwgY29kZWJvb2skRmllbGQpCgojIFJlcGxhY2UgIi0iIGluICJzaXBfc2NvcmUiIGFuZCAic2lwX2NvbW1lbnRzIiB3aXRoIE5BCmRhdGEkc2lwX2NvbW1lbnRzW2RhdGEkc2lwX2NvbW1lbnRzID09ICItIl0gPSBOQQpkYXRhJHNpcF9zY29yZVtkYXRhJHNpcF9zY29yZSA9PSAiLSJdID0gTkEKYGBgCgojIyBQQVJUIDE6IERhdGFzZXQgT3ZlcnZpZXcKYGBge3J9CiMgQ3JlYXRpbmcgc3VtbWFyeSBzdGF0aXN0aWNzIHRhYmxlCnN1bW1hcnkgPSBkYXRhLmZyYW1lKFZhcmlhYmxlID0gY29sbmFtZXMoZGF0YSkpCnN1bW1hcnkkRGF0YVR5cGUgPSBzYXBwbHkoZGF0YSwgY2xhc3MpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIENyZWF0aW5nIGNvbHVtbiAiRGF0YVR5cGUiIHRvIGluZGljYXRlIGFsbCB2YXJpYWJsZXMnIGRhdGEgdHlwZQpzdW1tYXJ5JE5BbnVtID0gc2FwcGx5KGRhdGEsIGZ1bmN0aW9uKHgpe3N1bShpcy5uYSh4KSl9KSAgICAgICAgICAgIyBDcmVhdGluZyBjb2x1bW4gIk5BbnVtIiB0byBjb3VudCB0aGUgbnVtYmVyIG9mIE5BcyBpbiBlYWNoIHZhcmlhYmxlCnN1bW1hcnkkdW5pcXVlTnVtID0gc2FwcGx5KGRhdGEsIGZ1bmN0aW9uKHgpe2xlbmd0aCh1bmlxdWUoeCkpfSkgICAjIENyZWF0aW5nIGNvbHVtbiAidW5pcXVlTnVtIiB0byBjb3VudCB0aGUgbnVtYmVyIG9mIHVuaXF1ZSB2YWx1ZXMgaW4gZWFjaCB2YXJpYWJsZQpzdW1tYXJ5JG1pbiA9IHNhcHBseShkYXRhLCBtaW4sIG5hLnJtID0gVFJVRSkgICAgICAgICAgICAgICAgICAgICAgIyBDcmVhdGluZyBjb2x1bW4gIm1pbiIgdG8gaW5kaWNhdGUgYWxsIHZhcmlhYmxlcycgbWluaW11bSB2YWx1ZSAob25seSBtZWFuaW5nZnVsIGZvciBudW1lcmljIHZhbHVlcykKc3VtbWFyeSRtYXggPSBzYXBwbHkoZGF0YSwgbWF4LCBuYS5ybSA9IFRSVUUpICAgICAgICAgICAgICAgICAgICAgICMgQ3JlYXRpbmcgY29sdW1uICJtYXgiIHRvIGluZGljYXRlIGFsbCB2YXJpYWJsZXMnIG1heGltdW0gdmFsdWUgKG9ubHkgbWVhbmluZ2Z1bCBmb3IgbnVtZXJpYyB2YWx1ZXMpCnN1bW1hcnkkbWVhbiA9IHNhcHBseShkYXRhLCBtZWFuLCBuYS5ybSA9IFRSVUUpICAgICAgICAgICAgICAgICAgICAjIENyZWF0aW5nIGNvbHVtbiAibWVhYiIgdG8gaW5kaWNhdGUgYWxsIHZhcmlhYmxlcycgbWVhbiAob25seSBtZWFuaW5nZnVsIGZvciBudW1lcmljIHZhbHVlcykKCiMgSm9pbiB2YXJpYWJsZSBkZWZpbml0aW9ucyBpbiBjb2RlYm9vayB0byBzdW1tYXJ5IHN0YXRpc3RpY3MgdGFibGUKc3VtbWFyeSA9IG1lcmdlKHN1bW1hcnksIGNvZGVib29rLCBieS54ID0gIlZhcmlhYmxlIiwgYnkueSA9ICJGaWVsZCIpCgojIExpc3QgNSBleGFtcGxlcyBvZiB0aGUgZmllbGQgdmFsdWVzIGZvciBlYWNoIHZhcmlhYmxlCmV4YW1wbGUgPSBzYXBwbHkoZGF0YSwgZnVuY3Rpb24oeCl7c29ydCh1bmlxdWUoeClbMTo1XSl9KSAgICAgICAgICMgZXh0cmFjdCBhbmQgc29ydCB1bmlxdWUgdmFsdWVzIGZvciBlYWNoIGNvbHVtbgpleGFtcGxlID0gbGRwbHkoZXhhbXBsZSwgcmJpbmQpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRyYW5zZm9ybSB0aGUgbGlzdCBpbnRvIGEgZGF0YWZyYW1lCmNvbG5hbWVzKGV4YW1wbGUpID0gYygiVmFyaWFibGUiLCAiZTEiLCAiZTIiLCAiZTMiLCAiZTQiLCAiZTUiKSAgICMgcmVuYW1lIHRoZSBjb2x1bW5zCmV4YW1wbGUkZXhhbXBsZXMgPSBhcHBseShleGFtcGxlWywtMV0sIDEsIHBhc3RlLCBjb2xsYXBzZSA9ICIvLyIpICMgcGFzdGUgYWxsIHRoZSA1IGV4YW1wbGVzIGZvciBlYWNoIHZhcmlhYmxlIGludG8gb25lIGNvbHVtbgpzdW1tYXJ5ID0gbWVyZ2Uoc3VtbWFyeSwgZXhhbXBsZVssIGMoMSwgNyldLCBieSA9ICJWYXJpYWJsZSIpICAgICAjIGpvaW4gdGhlIGV4YW1wbGVzIHRvIHRoZSBzdW1tYXJ5IHRhYmxlCgojIFdyaXRlIHRoZSBzdW1tYXJ5IHN0YXRpc3RpY3MgaW50byBjc3YgZmlsZQojZndyaXRlKHN1bW1hcnksICJzdW1tYXJ5LmNzdiIpCmBgYAoKU2luY2Ugb3VyIGJ1c2luZXNzIG9iamVjdGl2ZSBvbmx5IGRlYWxzIHdpdGggMXN0IHRpZXIgYWRtaXR0ZWQgc3R1ZGVudHMsIHdlIHdpbGwgb25seSBwZXJmb3JtIGNsZWFuaW5nIGFuZCBleHBsb3JhdG9yeSBhbmFseXNpcyBvbiB0aGUgMXN0IHRpZXIgYWRtaXR0ZWQgc3R1ZGVudHMuCmBgYHtyfQp0MSA9IGRhdGElPiUKICBmaWx0ZXIoZGVjaXNpb24gPT0gIjFzdCBUaWVyIEFkbWl0IikgI25vdCB1c2VkLiBSZWFzb25zIHN0YXRlZCBiZWxvdwpgYGAKCgojIyBQQVJUIDI6IEV4cGxvcmluZyBEYXRhIERpc3RyaWJ1dGlvbgpUaGVyZSBhcmUgYWx0b2dldGhlciA4MSB2YXJpYWJsZXMgaW4gdGhlIGRhdGFzZXQuIFdlIHdpbGwgZ28gb3ZlciBlYWNoIGNvbHVtbiBvbmUgYnkgb25lIHRvIHVuZGVyc3RhbmQgaXRzIGRldGFpbHMgYW5kIHRoZW4gZGVjaWRlIHRoZSBjb3JyZXNwb25kaW5nIGNsZWFuaW5nIG1ldGhvZC4KCjEuIG9wcG9ydHVuaXR5X2lkOiB0aGUgdW5pcXVlIGlkZW50aWZlciBvZiBlYWNoIGFwcGxpY2FudC4gCjIuIGFwcGxpY2F0aW9uX3Rlcm06IFRlcm0gYXBwbGllZCB0byBwcm9ncmFtClRoZXJlIGlzIGEgc3VkZGVuIGRyb3AgaW4gbnVtYmVyIG9mIGFwcGxpY2F0aW9ucyBmb3IgMXN0IHRpZXIgYWRtaXQgaW4gMjAxNSwgc28gSSBjaGVja2VkIHRoZSB3aG9sZSBkYXRhc2V0IHRvIHNlZSBpZiB0aGUgc3VkZGVuIGRyb3AgaXMgZHVlIHRvIHRoZSBkcm9wIGluIHRvdGFsIG51bWJlciBvZiBhcHBsaWNhdGlvbiwgYW5kIGZpbmQgdGhhdCB0aGUgZHJvcCBpcyB1bml2ZXJzYWwgYW1vbmcgYWxsIHN0dWRlbnRzLiAtLT4gT1VSIEJVU0lORVNTIE9CSkVDVElWRSBNQVkgTk9UIEJFIEZFQVNJQkxFIQpgYGB7cn0KIyBjbGFzcyh0MSRhcHBsaWNhdGlvbl90ZXJtKSAjZGF0YSB0eXBlIGlzIGNoYXJhY3RlcgojIAojICMgY29udmVydCB0aGUgZGF0YSB0eXBlIHRvIGZhY3RvciBhbmQgcmVvcmRlciB0aGUgbGV2ZWwgdG8gbWF0Y2ggYWN0dWFsIHNlbWVzdGVycyB0aW1lbGluZQojIHQxJGFwcGxpY2F0aW9uX3Rlcm0gPSBhcy5mYWN0b3IodDEkYXBwbGljYXRpb25fdGVybSkKIyBsZXZlbHModDEkYXBwbGljYXRpb25fdGVybSkgPSBsZXZlbHModDEkYXBwbGljYXRpb25fdGVybSlbYyg3LCAxLCA4LCAyLCA5LCAzLCAxMCwgNCwgNSwgNildIAojIGxldmVscyh0MSRhcHBsaWNhdGlvbl90ZXJtKQojIAojICMgZHJhdyB0aGUgcGxvdAojIGdncGxvdCh0MSwgYWVzKHggPSBhcHBsaWNhdGlvbl90ZXJtKSkrCiMgICBnZW9tX2JhcihmaWxsPSIjOTk5OTk5IikrCiMgICBsYWJzKHRpdGxlPSJEaXN0cmlidXRpb24gb2YgYXBwbGljYXRpb25fdGVybSIsIAojICAgICAgICB4PSJhcHBsaWNhdGlvbl90ZXJtIiwgCiMgICAgICAgIHk9IkNvdW50IikrCiMgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwKIyAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpCgojIGNvbnZlcnQgdGhlIGRhdGEgdHlwZSB0byBmYWN0b3IgYW5kIHJlb3JkZXIgdGhlIGxldmVsIHRvIG1hdGNoIGFjdHVhbCBzZW1lc3RlcnMgdGltZWxpbmUKZGF0YSRhcHBsaWNhdGlvbl90ZXJtID0gYXMuZmFjdG9yKGRhdGEkYXBwbGljYXRpb25fdGVybSkKbGV2ZWxzKGRhdGEkYXBwbGljYXRpb25fdGVybSkgPSBsZXZlbHMoZGF0YSRhcHBsaWNhdGlvbl90ZXJtKVtjKDEwLCAxLCAxMSwgMiwgNywgMTIsIDMsIDgsIDEzLCA0LCA1LCA5LCAxNCwgNildCgojIGRyYXcgdGhlIHBsb3QgKGdyZXkgaXMgYWxsIHN0dWRlbnRzLCByZWQgaXMgMXN0IHRpZXIgc3R1ZGVudHMpCmRhdGElPiUKICBmaWx0ZXIoIWlzLm5hKGFwcGxpY2F0aW9uX3Rlcm0pKSU+JQogIGdncGxvdChhZXMoeCA9IGFwcGxpY2F0aW9uX3Rlcm0pKSsKICBnZW9tX2JhcihmaWxsPSIjOTk5OTk5IikrCiAgbGFicyh0aXRsZT0iRGlzdHJpYnV0aW9uIG9mIGFwcGxpY2F0aW9uX3Rlcm0gKGZvciBhbGwgYXBwbGljYXRpb25zKSIsIAogICAgICAgeD0iYXBwbGljYXRpb25fdGVybSIsIAogICAgICAgeT0iQ291bnQiKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSsKICBnZW9tX2JhcihkYXRhID0gdDEsIGZpbGw9InJlZCIpKwogIGxhYnModGl0bGU9IkRpc3RyaWJ1dGlvbiBvZiBhcHBsaWNhdGlvbl90ZXJtIChmb3IgYWxsIGFwcGxpY2F0aW9ucykiLCAKICAgICAgIHg9ImFwcGxpY2F0aW9uX3Rlcm0iLCAKICAgICAgIHk9IkNvdW50IikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKCiMgZHJhdyB0aGUgY291bnQgZm9yIHN0dWRlbnRzIHdobyBjb25maXJtZWQgb2ZmZXIKZGF0YSU+JQogIGZpbHRlcihyZXNwb25zZSA9PSAiQ29uZmlybWVkIiklPiUKICBnZ3Bsb3QoYWVzKHggPSBhcHBsaWNhdGlvbl90ZXJtKSkrCiAgZ2VvbV9iYXIoZmlsbD0iIzk5OTk5OSIpKwogIGxhYnModGl0bGU9IkRpc3RyaWJ1dGlvbiBvZiBhcHBsaWNhdGlvbl90ZXJtIChmb3IgY29uZmlybWVkIHN0ZHVlbnRzKSIsIAogICAgICAgeD0iYXBwbGljYXRpb25fdGVybSIsIAogICAgICAgeT0iQ291bnQiKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQpgYGAKU28gd2UgcGVyZm9ybWVkIHRoZSByZXN0IG9mIHRoZSBFREEsIG9uIHRoZSBlbnRpcmUgZGF0YXNldAozLiBkZWdyZWVfcG9zdGVkOiBXaGVuIHRoZWlyIHVuZGVyZ3JhZHVhdGUgZGVncmVlIGNvbmZlcnJlZAoxIG91dGxpZXIgCmBgYHtyfQojIGRyYXcgdGhlIHBsb3QKZGF0YSU+JQogIGZpbHRlcihkZWdyZWVfcG9zdGVkIDwgIjIwMTktMDEtMDEiKSU+JQogIGdncGxvdChhZXMoeCA9IGRlZ3JlZV9wb3N0ZWQpKSsKICBnZW9tX3BvaW50KHN0YXQgPSAiY291bnQiKSsKICBsYWJzKHRpdGxlID0gJ0Rpc3RyaWJ1dGlvbiBvZiB1bmRlcmdyYWR1YXRlIGRlZ3JlZSBjb25mZXJyZWQgZGF0ZScpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLAogICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpKQpgYGAKCjQuIGFwcGxpY2F0aW9uX3JlY2VpdmVkX2RhdGU6IERhdGUgdGhlaXIgYXBwbGljYXRpb24gd2FzIHJlY2VpdmVkCm1hbnkgTkFzCmBgYHtyfQojIGFnZ3JlZ2F0ZWQKZGF0YSU+JQogIGZpbHRlcighaXMubmEoYXBwbGljYXRpb25fcmVjZWl2ZWRfZGF0ZSkpJT4lCiAgZ2dwbG90KGFlcyh4ID0gYXMuZmFjdG9yKG1vbnRoKGFwcGxpY2F0aW9uX3JlY2VpdmVkX2RhdGUpKSkpKwogIGdlb21fYmFyKGZpbGwgPSAiIzk5OTk5OSIpKwogIGxhYnModGl0bGUgPSAnRGlzdHJpYnV0aW9uIG9mIGFwcGxpY2F0aW9uX3JlY2VpdmVkX2RhdGUgKGFnZy4gdG8gbW9udGhzKScsCiAgICAgICB4ID0gIm1vbnRoIikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksCiAgICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkKCiMgYWNyb3NzIGFsbCB5ZWFycwpkYXRhJT4lCiAgZmlsdGVyKCFpcy5uYShhcHBsaWNhdGlvbl9yZWNlaXZlZF9kYXRlKSklPiUKICBnZ3Bsb3QoYWVzKHggPSBhcHBsaWNhdGlvbl9yZWNlaXZlZF9kYXRlKSkrCiAgZ2VvbV9wb2ludChzdGF0ID0gImNvdW50IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgYXBwbGljYXRpb25fcmVjZWl2ZWRfZGF0ZScsCiAgICAgICB4ID0gInRpbWUiKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwKICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpCmBgYAoKNS4gZmlsZV9zdGF0dXNfY29tcGxldGVkX2RhdGU6IERhdGUgdGhlaXIgYXBwbGljYXRpb24gZmlsZSB3YXMgY29tcGxldGVkCgpgYGB7cn0KIyBhZ2dyZWdhdGVkIHRvIG1vbnRocwpkYXRhJT4lCiAgZmlsdGVyKGZpbGVfc3RhdHVzX2NvbXBsZXRlZF9kYXRlIDwgIjIwMTktMDEtMDEiKSU+JQogIGdncGxvdChhZXMoeCA9IGFzLmZhY3Rvcihtb250aChmaWxlX3N0YXR1c19jb21wbGV0ZWRfZGF0ZSkpKSkrCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOTk5OTk5IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgZmlsZV9zdGF0dXNfY29tcGxldGVkX2RhdGUgKGFnZy4gdG8gbW9udGhzKScsCiAgICAgICB4ID0gIm1vbnRoIikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksCiAgICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkKCiMgYWNyb3NzIGFsbCB5ZWFycwpkYXRhJT4lCiAgZmlsdGVyKGZpbGVfc3RhdHVzX2NvbXBsZXRlZF9kYXRlIDwgIjIwMTktMDEtMDEiKSU+JQogIGdncGxvdChhZXMoeCA9IGZpbGVfc3RhdHVzX2NvbXBsZXRlZF9kYXRlKSkrCiAgZ2VvbV9wb2ludChzdGF0ID0gImNvdW50IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgZmlsZV9zdGF0dXNfY29tcGxldGVkX2RhdGUnLAogICAgICAgeCA9ICJ0aW1lIikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksCiAgICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkKYGBgCgo2LiBkZWNpc2lvbl9kYXRlOiBEYXRlIG9mIHRoZSBhZG1pdCBvciBkZW55IGRlY2lzaW9uIGZvciB0aGVpciBhcHBsaWNhdGlvbgpUaGVyZSBpcyBvbmUgb3V0bGllciBpbiB0aGlzIGZpZWxkIGFuZCBpcyBhcHBhcmVudGx5IGEgdHlwbywgd2hpY2ggaXMgZXhjbHVkZWQgZnJvbSB0aGUgZGF0YXNldApgYGB7cn0KIyBkcmF3IHRoZSBwbG90CmRhdGElPiUKICBmaWx0ZXIoZGVjaXNpb25fZGF0ZSA8ICIyMDE5LTAxLTAxIiklPiUKICBnZ3Bsb3QoYWVzKHggPSBhcy5mYWN0b3IobW9udGgoZGVjaXNpb25fZGF0ZSkpKSkrCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOTk5OTk5IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgZGVjaXNpb25fZGF0ZScsCiAgICAgICB4ID0gIm1vbnRoIikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksCiAgICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkKCiMgYWNyb3NzIGFsbCB5ZWFycwpkYXRhJT4lCiAgZmlsdGVyKGRlY2lzaW9uX2RhdGUgPCAiMjAxOS0wMS0wMSIpJT4lCiAgZ2dwbG90KGFlcyh4ID0gZGVjaXNpb25fZGF0ZSkpKwogIGdlb21fcG9pbnQoc3RhdCA9ICJjb3VudCIpKwogIGxhYnModGl0bGUgPSAnRGlzdHJpYnV0aW9uIG9mIGRlY2lzaW9uX2RhdGUnLAogICAgICAgeCA9ICJ0aW1lIikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksCiAgICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkKYGBgCgo3LiBhcHBsaWNhdGlvbl9jbGVhbmVkX2RhdGU6IERhdGUgdGhlaXIgYXBwbGljYXRpb24gd2FzIHByb2Nlc3NlZCBhZnRlciByZWNlaXZpbmcKYGBge3J9CiMgZHJhdyB0aGUgcGxvdApkYXRhJT4lCiAgZmlsdGVyKCFpcy5uYShhcHBsaWNhdGlvbl9jbGVhbmVkX2RhdGUpKSU+JQogIGdncGxvdChhZXMoeCA9IGFzLmZhY3Rvcihtb250aChhcHBsaWNhdGlvbl9jbGVhbmVkX2RhdGUpKSkpKwogIGdlb21fYmFyKGZpbGwgPSAiIzk5OTk5OSIpKwogIGxhYnModGl0bGUgPSAnRGlzdHJpYnV0aW9uIG9mIGFwcGxpY2F0aW9uX2NsZWFuZWRfZGF0ZScsCiAgICAgICB4ID0gIm1vbnRoIikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksCiAgICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkKCiMgYWNyb3NzIGFsbCB5ZWFycwpkYXRhJT4lCiAgZmlsdGVyKCFpcy5uYShhcHBsaWNhdGlvbl9jbGVhbmVkX2RhdGUpKSU+JQogIGdncGxvdChhZXMoeCA9IGFwcGxpY2F0aW9uX2NsZWFuZWRfZGF0ZSkpKwogIGdlb21fcG9pbnQoc3RhdCA9ICJjb3VudCIpKwogIGxhYnModGl0bGUgPSAnRGlzdHJpYnV0aW9uIG9mIGFwcGxpY2F0aW9uX2NsZWFuZWRfZGF0ZScsCiAgICAgICB4ID0gInRpbWUiKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwKICAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQpgYGAKCjguIGRlcG9zaXRfcmVjZWl2ZWRfZGF0ZQpgYGB7cn0KIyBkcmF3IHRoZSBwbG90CmRhdGElPiUKICBmaWx0ZXIoIWlzLm5hKGRlcG9zaXRfcmVjZWl2ZWRfZGF0ZSkpJT4lCiAgZ2dwbG90KGFlcyh4ID0gYXMuZmFjdG9yKG1vbnRoKGRlcG9zaXRfcmVjZWl2ZWRfZGF0ZSkpKSkrCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOTk5OTk5IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgZGVwb3NpdF9yZWNlaXZlZF9kYXRlJywKICAgICAgIHggPSAibW9udGgiKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwKICAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQoKIyBhY3Jvc3MgYWxsIHllYXJzCmRhdGElPiUKICBmaWx0ZXIoIWlzLm5hKGRlcG9zaXRfcmVjZWl2ZWRfZGF0ZSkpJT4lCiAgZ2dwbG90KGFlcyh4ID0gZGVwb3NpdF9yZWNlaXZlZF9kYXRlKSkrCiAgZ2VvbV9wb2ludChzdGF0ID0gImNvdW50IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgZGVwb3NpdF9yZWNlaXZlZF9kYXRlJywKICAgICAgIHggPSAidGltZSIpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLAogICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpCmBgYAoKOS4gZGVwYXJ0bWVudDogRGVwYXJ0bWVudCBvZiBzdHVkZW50cwpgYGB7cn0KIyBkcmF3IHRoZSBwbG90IGFuZCBleGNsdWRlIGFsbCBOQXMgKG1hbnkgTkFzKQpkYXRhJT4lCiAgZmlsdGVyKCFpcy5uYShkZXBhcnRtZW50KSklPiUKICBnZ3Bsb3QoYWVzKHggPSBkZXBhcnRtZW50KSkrCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOTk5OTk5IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgZGVwYXJ0bWVudCcpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLAogICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpCmBgYAoKMTAuIHVuZGVyZ3JhZHVhdGVfZ3BhOiBjYWxjdWxhdGVkIGJ5IFVTQwpgYGB7cn0KI3Bsb3QKZGF0YSU+JQogIGZpbHRlcih1bmRlcmdyYWR1YXRlX2dwYSAhPSAwKSU+JQogIGdncGxvdChhZXMoeCA9IHVuZGVyZ3JhZHVhdGVfZ3BhKSkrCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOTk5OTk5IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgdW5kZXJncmFkdWF0ZV9ncGEnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwKICAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQpgYGAKCjExLiBzZWxmX3JlcG9ydGVkX2dwYQpPdXRsaWVycyB3aXRoIHNlbGYgcmVwb3J0ZWQgZ3BhIGdyZWF0ZXIgdGhhbiA1IGFuZCBlcXVhbHMgdG8gMCAoc2hvdWxkIGJlIGNsZWFuZWQpCmBgYHtyfQojcGxvdApkYXRhJT4lCiAgZmlsdGVyKHNlbGZfcmVwb3J0ZWRfZ3BhIDw9IDQgJiBzZWxmX3JlcG9ydGVkX2dwYSAhPSAwKSU+JQogIGdncGxvdChhZXMoeCA9IHNlbGZfcmVwb3J0ZWRfZ3BhKSkrCiAgZ2VvbV9wb2ludChzdGF0ID0gImNvdW50IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2Ygc2VsZl9yZXBvcnRlZF9ncGEnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwKICAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQoKI3Bsb3Qgc2VsZl9yZXBvcnRlZF9ncGEgd2l0aCB1bmRlcmdyYWR1YXRlIGdwYSBjYWxjdWx0ZWQgYnkgVVNDCmRhdGElPiUKICBmaWx0ZXIoc2VsZl9yZXBvcnRlZF9ncGEgPD0gNCAmIHNlbGZfcmVwb3J0ZWRfZ3BhICE9IDApJT4lCiAgZmlsdGVyKHVuZGVyZ3JhZHVhdGVfZ3BhICE9IDApJT4lCiAgZ2dwbG90KGFlcyh4ID0gdW5kZXJncmFkdWF0ZV9ncGEpKSsKICBnZW9tX2JhcihmaWxsID0gIiM5OTk5OTkiKSsKICBnZW9tX3BvaW50KGFlcyh4ID0gc2VsZl9yZXBvcnRlZF9ncGEpLCBzdGF0ID0gImNvdW50IiwgY29sb3IgPSAicmVkIikrCiAgICBsYWJzKHRpdGxlID0gJ3NlbGZfcmVwb3J0ZWRfZ3BhIChyZWQpIGFnYWluc3QgdW5kZXJncmFkdWF0ZV9ncGEnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwKICAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQpgYGAKCjEyLiBmaXJzdF9yZXZpZXdlcl9pZApgYGB7cn0KI3Bsb3QKZGF0YSU+JQogIGZpbHRlcighaXMubmEoZmlyc3RfcmV2aWV3ZXJfaWQpKSU+JQogIGdncGxvdChhZXMoeCA9IGZpcnN0X3Jldmlld2VyX2lkKSkrCiAgZ2VvbV9wb2ludChzdGF0ID0gImNvdW50IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgZmlyc3RfcmV2aWV3ZXJfaWQnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQpgYGAKCjEzLiBmaXJzdF9yZXZpZXdfZXhwOiBGaXJzdCByZXZpZXdlciBzY29yZSBmb3IgZXhwZXJpZW5jZQpgYGB7cn0KZGF0YSU+JQogIGdncGxvdChhZXMoeCA9IGZpcnN0X3Jldmlld19leHApKSsKICBnZW9tX2JhcihmaWxsID0gIiM5OTk5OTkiKSsKICBsYWJzKHRpdGxlID0gJ0Rpc3RyaWJ1dGlvbiBvZiBmaXJzdF9yZXZpZXdfZXhwJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCmBgYAoKMTQuIGZpcnN0X3Jldmlld19zb3A6IEZpcnN0IHJldmlld2VyIHNjb3JlIGZvciBzdGF0ZW1lbnQgb2YgcHVycG9zZQpgYGB7cn0KZGF0YSU+JQogIGdncGxvdChhZXMoeCA9IGZpcnN0X3Jldmlld19zb3ApKSsKICBnZW9tX2JhcihmaWxsID0gIiM5OTk5OTkiKSsKICBsYWJzKHRpdGxlID0gJ0Rpc3RyaWJ1dGlvbiBvZiBmaXJzdF9yZXZpZXdfc29wJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCmBgYAoKMTUuIGZpcnN0X3Jldmlld19ncGE6IEZpcnN0IHJldmlld2VyIHNjb3JlIGZvciBHUEEgKHVuZGVyZ3JhZCBhbmQgZ3JhZCkKYGBge3J9CmRhdGElPiUKICBnZ3Bsb3QoYWVzKHggPSBmaXJzdF9yZXZpZXdfZ3BhKSkrCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOTk5OTk5IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgZmlyc3RfcmV2aWV3X2dwYScpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQpgYGAKCjE2LiBmaXJzdF9yZXZpZXdfbG9yOiBsZXR0ZXJzIG9mIHJlY29tbWVuZGF0aW9uCmBgYHtyfQpkYXRhJT4lCiAgZ2dwbG90KGFlcyh4ID0gZmlyc3RfcmV2aWV3X2xvcikpKwogIGdlb21fYmFyKGZpbGwgPSAiIzk5OTk5OSIpKwogIGxhYnModGl0bGUgPSAnRGlzdHJpYnV0aW9uIG9mIGZpcnN0X3Jldmlld19sb3InKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKYGBgCgoxNy4gZmlyc3RfcmV2aWV3X3RvdGFsOiB0b3RhbCBzY29yZQpgYGB7cn0KZGF0YSU+JQogIGdncGxvdChhZXMoeCA9IGZpcnN0X3Jldmlld190b3RhbCkpKwogIGdlb21fYmFyKGZpbGwgPSAiIzk5OTk5OSIpKwogIGxhYnModGl0bGUgPSAnRGlzdHJpYnV0aW9uIG9mIGZpcnN0X3Jldmlld190b3RhbCcpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQpgYGAKCjE4LiBzZWNvbmRfcmV2aWV3ZXJfaWQKYGBge3J9CiNwbG90CmRhdGElPiUKICBmaWx0ZXIoIWlzLm5hKHNlY29uZF9yZXZpZXdlcl9pZCkpJT4lCiAgZ2dwbG90KGFlcyh4ID0gc2Vjb25kX3Jldmlld2VyX2lkKSkrCiAgZ2VvbV9wb2ludChzdGF0ID0gImNvdW50IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2Ygc2Vjb25kX3Jldmlld2VyX2lkJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKYGBgCgoxOS4gc2Vjb25kX3Jldmlld19leHA6IHNlY29uZCByZXZpZXdlciBzY29yZSBmb3IgZXhwZXJpZW5jZQpgYGB7cn0KZGF0YSU+JQogIGdncGxvdChhZXMoeCA9IHNlY29uZF9yZXZpZXdfZXhwKSkrCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOTk5OTk5IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2Ygc2Vjb25kX3Jldmlld19leHAnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKYGBgCgoyMC4gc2Vjb25kX3Jldmlld19zb3A6IHNlY29uZCByZXZpZXdlciBzY29yZSBmb3Igc3RhdGVtZW50IG9mIHB1cnBvc2UKYGBge3J9CmRhdGElPiUKICBnZ3Bsb3QoYWVzKHggPSBzZWNvbmRfcmV2aWV3X3NvcCkpKwogIGdlb21fYmFyKGZpbGwgPSAiIzk5OTk5OSIpKwogIGxhYnModGl0bGUgPSAnRGlzdHJpYnV0aW9uIG9mIHNlY29uZF9yZXZpZXdfc29wJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCmBgYAoKMjEuIHNlY29uZF9yZXZpZXdfZ3BhOiBzZWNvbmQgcmV2aWV3ZXIgc2NvcmUgZm9yIEdQQSAodW5kZXJncmFkIGFuZCBncmFkKQpgYGB7cn0KZGF0YSU+JQogIGdncGxvdChhZXMoeCA9IHNlY29uZF9yZXZpZXdfZ3BhKSkrCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOTk5OTk5IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2Ygc2Vjb25kX3Jldmlld19ncGEnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKYGBgCgoyMi4gY29uY2VudHJhdGlvbi9kZXBhcnRtZW50X2ludGVyZXN0OiBEZXBhcnRtZW50IG9mIHN0dWRlbnQuIApUaGlzIG9uZSBpcyB0aGUgdW5vZmZpY2lhbCBvbmUgKCJkZXBhcnRtZW50IiBpcyB0aGUgb2ZmaWNpYWwgb25lKSwgcHJvYmFibHkgbWFudWFsbHkgZmlsbGVkIGFuZCB0aHVzIGlzIHZlcnkgbWVzc3kuIFdlIGNhbiBkaXJlY3RseSB1c2UgCgoyMy4gZmlyc3RfcmV2aWV3X2xvcjogbGV0dGVycyBvZiByZWNvbW1lbmRhdGlvbgpgYGB7cn0KZGF0YSU+JQogIGdncGxvdChhZXMoeCA9IHNlY29uZF9yZXZpZXdfbG9yKSkrCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOTk5OTk5IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2Ygc2Vjb25kX3Jldmlld19sb3InKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKYGBgCgoyNC4gc2Vjb25kX3Jldmlld190b3RhbDogdG90YWwgc2NvcmUKYGBge3J9CmRhdGElPiUKICBnZ3Bsb3QoYWVzKHggPSBzZWNvbmRfcmV2aWV3X3RvdGFsKSkrCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOTk5OTk5IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2Ygc2Vjb25kX3Jldmlld190b3RhbCcpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQpgYGAKCjI1LiBiaWxsaW5nX3N0YXRlL3Byb3ZpbmNlCk1hbnVhbGx5IGlucHV0IGRhdGEgYW5kIHRodXMgdmVyeSBtZXNzeS4gTG90cyBvZiBpbmNvbnNpc3RlbnQgd3JpdGluZyBvZiBzYW1lIGdlb2dyYXBoaWNhbCBsb2NhdGlvbiwgc3VjaCBhcyAiQ0EiIGFuZCAiQ2FsaWZvcm5pYSIuCgoyNi4gYmlsbGluZ196aXAvcG9zdGFsX2NvZGUKCjI3LiBiaWxsaW5nX2NvdW50cnkKYGBge3J9CmRhdGEkYmlsbGluZ19jb3VudHJ5W2RhdGEkYmlsbGluZ19jb3VudHJ5ICVpbiUgYygidW5pdGVkIFN0YXRlcyIsICJVbml0ZWQiLCAiVVNBIiwgIlVuaXRlZCBTdGF0ZXMgb2YgQW1lcmljYSIsICJDQSIpXSA9ICJVbml0ZWQgU3RhdGVzIgoKZGF0YSU+JQogIGZpbHRlcighaXMubmEoYmlsbGluZ19jb3VudHJ5KSklPiUKICBncm91cF9ieShiaWxsaW5nX2NvdW50cnkpJT4lCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSU+JQogIGdncGxvdChhZXMoeCA9IHJlb3JkZXIoYmlsbGluZ19jb3VudHJ5LCAtY291bnQpLCB5ID0gY291bnQpKSsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICIjOTk5OTk5IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgYmlsbGluZ19jb3VudHJ5JykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKYGBgCgoyOC4gZGlzdGFuY2VfdG9fY2FtcHVzCmBgYHtyfQpkYXRhJT4lCiAgZ2dwbG90KGFlcyh4ID0gZGlzdGFuY2VfdG9fY2FtcHVzKSkrCiAgZ2VvbV9wb2ludChzdGF0ID0gImNvdW50IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgZGlzdGFuY2VfdG9fY2FtcHVzJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCmBgYAoKMjkuIHByb2dyYW1fbGVuZ3RoCmBgYHtyfQpkYXRhJHByb2dyYW1fbGVuZ3RoID0gYXMuZmFjdG9yKGRhdGEkcHJvZ3JhbV9sZW5ndGgpCmxldmVscyhkYXRhJHByb2dyYW1fbGVuZ3RoKSA9IGxldmVscyhkYXRhJHByb2dyYW1fbGVuZ3RoKVtjKDIsIDQsIDYsIDcsIDEsIDgsIDMsIDUpXQoKZGF0YSU+JQogIGZpbHRlcighaXMubmEocHJvZ3JhbV9sZW5ndGgpKSU+JQogIGdncGxvdChhZXMoeCA9IHByb2dyYW1fbGVuZ3RoKSkrCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOTk5OTk5IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgcHJvZ3JhbV9sZW5ndGgnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKYGBgCgozMC4gc3R1ZGVudF9pZCAoY2FuIGJlIHVzZWQgYXMgdGhlIHVuaXF1ZSBpZGVudGlmaWVyIGFzICJvcHBvcnR1bml0eSBpZCIpCgozMS4gcG9zdF9jb2RlOiBtZWFuaW5nIHByb2dyYW0gb2Ygc3R1ZHkKYGBge3J9CmRhdGElPiUKICBmaWx0ZXIoIWlzLm5hKHBvc3RfY29kZSkgJiAhcG9zdF9jb2RlICVpbiUgYygiRmFsbCAyMDE1IiwgIjE2NDU7MjY0IiwgIjI2NDsxNDEyIiwgIjI2NDsxNDExIiwgIjI2NDsyNjQiLCAiMjcyOzI2NCIpKSU+JQogIGdyb3VwX2J5KHBvc3RfY29kZSklPiUKICBzdW1tYXJpc2UoY291bnQgPSBuKCkpJT4lCiAgZ2dwbG90KGFlcyh4ID0gcmVvcmRlcihwb3N0X2NvZGUsIC1jb3VudCksIHkgPSBjb3VudCkpKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gIiM5OTk5OTkiKSsKICBsYWJzKHRpdGxlID0gJ0Rpc3RyaWJ1dGlvbiBvZiBwb3N0X2NvZGUnLAogICAgICAgeCA9ICdwb3N0X2NvZGUnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKYGBgCgozMi4gcG9zdF9jb2RlX2V4cGlyZWQgKHdoZXRoZXIgdGhlIGFwcGxpY2FudCBzd2l0Y2hlZCBmcm9tIGFub3RoZXIgcHJvZ3JhbSkKYGBge3J9CmRhdGElPiUKICBnZ3Bsb3QoYWVzKHggPSBwb3N0X2NvZGVfZXhwaXJlZCkpKwogIGdlb21fYmFyKGZpbGwgPSAiIzk5OTk5OSIpKwogIGxhYnModGl0bGUgPSAnRGlzdHJpYnV0aW9uIG9mIHBvc3RfY29kZV9leHBpcmVkJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCmBgYAoKMzMuIGZpbGVfc3RhdHVzCmBgYHtyfQpkYXRhJT4lCiAgZ2dwbG90KGFlcyh4ID0gZmlsZV9zdGF0dXMpKSsKICBnZW9tX2JhcihmaWxsID0gIiM5OTk5OTkiKSsKICBsYWJzKHRpdGxlID0gJ0Rpc3RyaWJ1dGlvbiBvZiBmaWxlX3N0YXR1cycpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQoKI3JlbW92ZSBOQQpkYXRhJT4lCiAgZmlsdGVyKCFpcy5uYShmaWxlX3N0YXR1cykpJT4lCiAgZ2dwbG90KGFlcyh4ID0gZmlsZV9zdGF0dXMpKSsKICBnZW9tX2JhcihmaWxsID0gIiM5OTk5OTkiKSsKICBsYWJzKHRpdGxlID0gJ0Rpc3RyaWJ1dGlvbiBvZiBmaWxlX3N0YXR1cycpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQpgYGAKCjM0LiBiaXJ0aF9kYXRlOiBkb2Igb2YgdGhlIGFwcGxpY2FudApgYGB7cn0KZGF0YSU+JQogIGZpbHRlcighaXMubmEoYmlydGhfZGF0ZSkgJiBiaXJ0aF9kYXRlIDwgIjIwMDAtMDEtMDEiKSU+JQogIGdncGxvdChhZXMoeCA9IGFzLmZhY3Rvcih5ZWFyKGJpcnRoX2RhdGUpKSkpKwogIGdlb21fYmFyKGZpbGwgPSAiIzk5OTk5OSIpKwogIGxhYnModGl0bGUgPSAnRGlzdHJpYnV0aW9uIG9mIGJpcnRoX2RhdGUnLAogICAgICAgeCA9ICdiaXJ0aF9kYXRlICh5ZWFyKScpKwogIHNjYWxlX3hfZGlzY3JldGUoYnJlYWtzID0gc2VxKDE5MzAsIDIwMDAsIGJ5ID0gMTApKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwKICAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSkKYGBgCgozNS4gZXRobmljaXR5CmBgYHtyfQpkYXRhJT4lCiAgZmlsdGVyKCFpcy5uYShldGhuaWNpdHkpKSU+JQogIGdyb3VwX2J5KGV0aG5pY2l0eSklPiUKICBzdW1tYXJpc2UoY291bnQgPSBuKCkpJT4lCiAgZ2dwbG90KGFlcyh4ID0gcmVvcmRlcihldGhuaWNpdHksIC1jb3VudCksIHkgPSBjb3VudCkpKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gIiM5OTk5OTkiKSsKICBsYWJzKHRpdGxlID0gJ0Rpc3RyaWJ1dGlvbiBvZiBldGhuaWNpdHknKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQpgYGAKCjM2LiBnZW5kZXIKYGBge3J9CmRhdGElPiUKICBmaWx0ZXIoIWlzLm5hKGdlbmRlcikpJT4lCiAgZ2dwbG90KGFlcyh4ID0gZ2VuZGVyKSkrCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOTk5OTk5IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgZ2VuZGVyJykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCmBgYAoKMzcuIGNhbXB1czogQ2FtcHVzIG9mIHN0dWR5IG9mIGFwcGxpY2FudApgYGB7cn0KZGF0YSU+JQogIGZpbHRlcighaXMubmEoY2FtcHVzKSklPiUKICBnZ3Bsb3QoYWVzKHggPSBjYW1wdXMpKSsKICBnZW9tX2JhcihmaWxsID0gIiM5OTk5OTkiKSsKICBsYWJzKHRpdGxlID0gJ0Rpc3RyaWJ1dGlvbiBvZiBjYW1wdXMnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQpgYGAKCjM4LiBmaXJzdF9nZW5lcmF0aW9uCmBgYHtyfQpkYXRhJT4lCiAgZmlsdGVyKCFpcy5uYShmaXJzdF9nZW5lcmF0aW9uKSklPiUKICBnZ3Bsb3QoYWVzKHggPSBmaXJzdF9nZW5lcmF0aW9uKSkrCiAgZ2VvbV9iYXIoZmlsbCA9ICIjOTk5OTk5IikrCiAgbGFicyh0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgZmlyc3RfZ2VuZXJhdGlvbicpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQpgYGAKCjM5LiBwb3N0X2NvZGVfYWNjb3VudApgYGB7cn0KZGF0YSU+JQogIGZpbHRlcighaXMubmEocG9zdF9jb2RlKSAmICFwb3N0X2NvZGUgJWluJSBjKCJGYWxsIDIwMTUiLCAiMTY0NTsyNjQiLCAiMjY0OzE0MTIiLCAiMjY0OzE0MTEiLCAiMjY0OzI2NCIsICIyNzI7MjY0IikpJT4lCiAgZ3JvdXBfYnkocG9zdF9jb2RlX2FjY291bnQpJT4lCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSU+JQogIGdncGxvdChhZXMoeCA9IHJlb3JkZXIocG9zdF9jb2RlX2FjY291bnQsIC1jb3VudCksIHkgPSBjb3VudCkpKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gIiM5OTk5OTkiKSsKICBsYWJzKHRpdGxlID0gJ0Rpc3RyaWJ1dGlvbiBvZiBwb3N0X2NvZGVfYWNjb3VudCcsCiAgICAgICB4ID0gJ3Bvc3RfY29kZV9hY2NvdW50JykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCmBgYAoKMzguIHJlZ2lzdGVyZWRfdW5pdHNfYWNjb3VudApgYGB7cn0KZGF0YSU+JQogIGZpbHRlcighaXMubmEocmVnaXN0ZXJlZF91bml0c19hY2NvdW50KSklPiUKICBnZ3Bsb3QoYWVzKHggPSByZWdpc3RlcmVkX3VuaXRzX2FjY291bnQpKSsKICBnZW9tX2JhcihmaWxsID0gIiM5OTk5OTkiKSsKICBsYWJzKHRpdGxlID0gJ0Rpc3RyaWJ1dGlvbiBvZiByZWdpc3RlcmVkX3VuaXRzX2FjY291bnQnKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKYGBgCgo0MC4gZGVwYXJ0bWVudF9zdHVkZW50X2FjY291bnQKYGBge3J9CmRhdGElPiUKICBmaWx0ZXIoIWlzLm5hKGRlcGFydG1lbnRfc3R1ZGVudF9hY2NvdW50KSklPiUKICBnZ3Bsb3QoYWVzKHggPSBkZXBhcnRtZW50X3N0dWRlbnRfYWNjb3VudCkpKwogIGdlb21fYmFyKGZpbGwgPSAiIzk5OTk5OSIpKwogIGxhYnModGl0bGUgPSAnRGlzdHJpYnV0aW9uIG9mIGRlcGFydG1lbnRfc3R1ZGVudF9hY2NvdW50JykrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCmBgYAoK